<template>
  <div class="fault-prediction-modeling">
    <!-- 顶部栏 -->
    <div class="header">
      <h2>故障预测建模</h2>
      <el-button type="primary" @click="openCreateModel">新建模型</el-button>
    </div>

    <!-- 主体内容 -->
    <el-row :gutter="20" class="main-content">
      <!-- 左侧：模型统计与管理 -->
      <el-col :span="16">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-card>
              <div class="stat-title">总模型数量</div>
              <div class="stat-value">{{ models.length }}</div>
            </el-card>
          </el-col>
          <el-col :span="8">
            <el-card>
              <div class="stat-title">运行中模型</div>
              <div class="stat-value">{{ runningModels.length }}</div>
            </el-card>
          </el-col>
          <el-col :span="8">
            <el-card>
              <div class="stat-title">平均准确率</div>
              <div class="stat-value">{{ avgAccuracy }}%</div>
            </el-card>
          </el-col>
        </el-row>

        <!-- 模型卡片列表 -->
        <el-tabs v-model="modelTab" class="model-tabs">
          <el-tab-pane label="进行中的模型" name="running">
            <el-row :gutter="20">
              <el-col :span="8" v-for="model in runningModels" :key="model.id">
                <el-card class="model-card">
                  <div class="model-title">{{ model.name }}</div>
                  <div class="model-algo">算法：{{ model.algorithm }}</div>
                  <div>训练进度：<el-progress :percentage="model.progress" /></div>
                  <div>准确率：<span :style="{color: '#409EFF'}">{{ model.accuracy }}%</span></div>
                  <div class="model-actions">
                    <el-button size="mini" @click="viewModel(model)">查看</el-button>
                    <el-button size="mini" @click="editModel(model)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="deleteModel(model)">删除</el-button>
                  </div>
                </el-card>
              </el-col>
            </el-row>
          </el-tab-pane>
          <el-tab-pane label="已完成的模型" name="finished">
            <el-row :gutter="20">
              <el-col :span="8" v-for="model in finishedModels" :key="model.id">
                <el-card class="model-card">
                  <div class="model-title">{{ model.name }}</div>
                  <div class="model-algo">算法：{{ model.algorithm }}</div>
                  <div>准确率：<span :style="{color: '#67C23A'}">{{ model.accuracy }}%</span></div>
                  <div class="model-actions">
                    <el-button size="mini" @click="viewModel(model)">查看</el-button>
                    <el-button size="mini" @click="editModel(model)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="deleteModel(model)">删除</el-button>
                  </div>
                </el-card>
              </el-col>
            </el-row>
          </el-tab-pane>
        </el-tabs>

        <!-- 模型训练趋势 -->
        <el-card class="trend-card">
          <div slot="header">模型训练趋势</div>
          <div>
            <el-table :data="trainTrend" border size="mini">
              <el-table-column prop="month" label="月份" width="80"/>
              <el-table-column prop="count" label="训练次数"/>
            </el-table>
          </div>
        </el-card>
      </el-col>

      <!-- 右侧：算法分布、最近活动、数据更新 -->
      <el-col :span="8">
        <el-card>
          <div slot="header">模型算法分布</div>
          <div>
            <canvas ref="algoChart" width="200" height="200"></canvas>
          </div>
        </el-card>
        <el-card class="activity-card">
          <div slot="header">最近活动</div>
          <el-table :data="recentActivities" border size="mini">
            <el-table-column prop="model" label="模型名称"/>
            <el-table-column prop="action" label="操作类型"/>
            <el-table-column prop="time" label="操作时间"/>
            <el-table-column prop="user" label="操作人"/>
            <el-table-column prop="status" label="状态"/>
          </el-table>
        </el-card>
        <el-card>
          <div slot="header">
            数据更新
            <el-button size="mini" style="float:right" @click="openDataUpdate">数据更新</el-button>
          </div>
          <div>
            <el-table :data="dataUpdates" border size="mini">
              <el-table-column prop="date" label="日期"/>
              <el-table-column prop="desc" label="描述"/>
            </el-table>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 新建模型弹窗 -->
    <el-dialog title="新建模型" :visible.sync="createModelDialog">
      <el-form :model="newModel" label-width="80px">
        <el-form-item label="模型名称">
          <el-input v-model="newModel.name" />
        </el-form-item>
        <el-form-item label="算法类型">
          <el-select v-model="newModel.algorithm" placeholder="请选择">
            <el-option label="XGBoost" value="XGBoost"/>
            <el-option label="随机森林" value="随机森林"/>
            <el-option label="LightGBM" value="LightGBM"/>
            <el-option label="其他" value="其他"/>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="createModelDialog=false">取消</el-button>
        <el-button type="primary" @click="nextToDataIntegration">下一步</el-button>
      </div>
    </el-dialog>

    <!-- 数据整合弹窗 -->
    <el-dialog title="数据整合" :visible.sync="dataIntegrationDialog" width="600px">
      <div>
        <el-alert title="请导入历史故障数据、运行参数、维护记录等多维度数据" type="info" show-icon/>
        <el-form label-width="120px" style="margin-top: 20px;">
          <el-form-item label="历史故障数据">
            <el-upload
              :auto-upload="false"
              :show-file-list="true"
              :on-change="handleFileChange('fault')"
              :file-list="dataFiles.fault"
              accept=".csv,.xlsx"
            >
              <el-button size="mini">导入文件</el-button>
            </el-upload>
          </el-form-item>
          <el-form-item label="运行参数">
            <el-upload
              :auto-upload="false"
              :show-file-list="true"
              :on-change="handleFileChange('param')"
              :file-list="dataFiles.param"
              accept=".csv,.xlsx"
            >
              <el-button size="mini">导入文件</el-button>
            </el-upload>
          </el-form-item>
          <el-form-item label="维护记录">
            <el-upload
              :auto-upload="false"
              :show-file-list="true"
              :on-change="handleFileChange('maintain')"
              :file-list="dataFiles.maintain"
              accept=".csv,.xlsx"
            >
              <el-button size="mini">导入文件</el-button>
            </el-upload>
          </el-form-item>
        </el-form>
        <el-alert title="已自动完成数据预处理（缺失值填充、异常值处理、特征归一化等）" type="success" show-icon style="margin-top: 10px;"/>
      </div>
      <div slot="footer">
        <el-button @click="dataIntegrationDialog=false">取消</el-button>
        <el-button type="primary" @click="nextToTrainConfig">下一步</el-button>
      </div>
    </el-dialog>

    <!-- 训练配置弹窗 -->
    <el-dialog title="模型训练配置" :visible.sync="trainConfigDialog" width="500px">
      <el-form :model="trainConfig" label-width="120px">
        <el-form-item label="训练/测试集比例">
          <el-slider v-model="trainConfig.split" :min="50" :max="90" :step="5" show-input :format-tooltip="v=>v+'%/ '+(100-v)+'%'" />
        </el-form-item>
        <el-form-item label="训练参数">
          <el-input v-model="trainConfig.params" placeholder="如：learning_rate=0.1, n_estimators=100"/>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="trainConfigDialog=false">取消</el-button>
        <el-button type="primary" :loading="trainLoading" @click="startTrain">开始训练</el-button>
      </div>
    </el-dialog>

    <!-- 训练结果弹窗 -->
    <el-dialog title="训练结果" :visible.sync="trainResultDialog" width="400px">
      <div>
        <el-alert title="设备剩余寿命（RUL）预测结果" type="info" show-icon/>
        <div style="margin: 20px 0;">
          <div>准确率：<b>{{ trainResult.accuracy }}%</b></div>
          <div>均方误差（MSE）：<b>{{ trainResult.mse }}</b></div>
          <div>R2分数：<b>{{ trainResult.r2 }}</b></div>
        </div>
      </div>
      <div slot="footer">
        <el-button type="primary" @click="finishTrain">完成</el-button>
      </div>
    </el-dialog>

    <!-- 数据更新弹窗 -->
    <el-dialog title="数据更新" :visible.sync="dataUpdateDialog" width="500px">
      <el-alert title="新故障案例和数据已自动纳入训练数据，模型参数已动态调整" type="success" show-icon/>
      <el-table :data="newDataCases" border size="mini" style="margin: 20px 0;">
        <el-table-column prop="date" label="日期"/>
        <el-table-column prop="desc" label="描述"/>
      </el-table>
      <div slot="footer">
        <el-button @click="dataUpdateDialog=false">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { Message } from 'element-ui'

const LOCAL_KEY = 'fault_prediction_models_v2'

function getMockModels() {
  return [
    {
      id: 1,
      name: '设备A预测模型',
      algorithm: 'XGBoost',
      status: 'running',
      progress: 100,
      accuracy: 95.8,
      created: '2024-01-10',
      updated: '2024-01-15 14:30'
    },
    {
      id: 2,
      name: '设备B预测模型',
      algorithm: '随机森林',
      status: 'running',
      progress: 100,
      accuracy: 92.5,
      created: '2024-01-10',
      updated: '2024-01-15 12:20'
    },
    {
      id: 3,
      name: '设备C预测模型',
      algorithm: 'LightGBM',
      status: 'finished',
      progress: 100,
      accuracy: 94.2,
      created: '2024-01-05',
      updated: '2024-01-14 16:45'
    }
  ]
}

function getMockActivities() {
  return [
    { model: '设备A预测模型', action: '模型训练', time: '2024-01-15 14:30', user: '张工', status: '进行中' },
    { model: '设备B预测模型', action: '模型评估', time: '2024-01-15 12:20', user: '李工', status: '已完成' },
    { model: '设备C预测模型', action: '参数调整', time: '2024-01-14 09:20', user: '王工', status: '已完成' }
  ]
}

function getMockDataUpdates() {
  return [
    { date: '2024-01-16', desc: '新增设备D故障案例' },
    { date: '2024-01-15', desc: '采集设备B运行参数' }
  ]
}

function getMockTrainTrend() {
  return [
    { month: '1月', count: 12 },
    { month: '2月', count: 15 },
    { month: '3月', count: 14 },
    { month: '4月', count: 17 },
    { month: '5月', count: 21 },
    { month: '6月', count: 28 }
  ]
}

export default {
  name: 'FaultPredictionModeling',
  data() {
    return {
      // 页面数据
      models: [],
      recentActivities: [],
      dataUpdates: [],
      trainTrend: [],
      modelTab: 'running',

      // 新建模型弹窗
      createModelDialog: false,
      newModel: {
        name: '',
        algorithm: ''
      },

      // 数据整合弹窗
      dataIntegrationDialog: false,
      dataFiles: {
        fault: [],
        param: [],
        maintain: []
      },

      // 训练配置弹窗
      trainConfigDialog: false,
      trainConfig: {
        split: 80,
        params: ''
      },
      trainLoading: false,

      // 训练结果弹窗
      trainResultDialog: false,
      trainResult: {
        accuracy: 0,
        mse: 0,
        r2: 0
      },

      // 数据更新弹窗
      dataUpdateDialog: false,
      newDataCases: [
        { date: '2024-01-16', desc: '新增设备D故障案例' },
        { date: '2024-01-15', desc: '采集设备B运行参数' }
      ]
    }
  },
  computed: {
    runningModels() {
      return this.models.filter(m => m.status === 'running')
    },
    finishedModels() {
      return this.models.filter(m => m.status === 'finished')
    },
    avgAccuracy() {
      if (!this.models.length) return 0
      const sum = this.models.reduce((acc, m) => acc + (m.accuracy || 0), 0)
      return (sum / this.models.length).toFixed(1)
    }
  },
  mounted() {
    this.loadData()
    this.drawAlgoChart()
  },
  watch: {
    models: {
      handler() {
        this.saveData()
        this.$nextTick(this.drawAlgoChart)
      },
      deep: true
    }
  },
  methods: {
    // 数据持久化
    loadData() {
      const local = localStorage.getItem(LOCAL_KEY)
      if (local) {
        const data = JSON.parse(local)
        this.models = data.models || []
        this.recentActivities = data.activities || []
        this.dataUpdates = data.dataUpdates || []
        this.trainTrend = data.trainTrend || []
      } else {
        this.models = getMockModels()
        this.recentActivities = getMockActivities()
        this.dataUpdates = getMockDataUpdates()
        this.trainTrend = getMockTrainTrend()
        this.saveData()
      }
    },
    saveData() {
      localStorage.setItem(LOCAL_KEY, JSON.stringify({
        models: this.models,
        activities: this.recentActivities,
        dataUpdates: this.dataUpdates,
        trainTrend: this.trainTrend
      }))
    },

    // 新建模型流程
    openCreateModel() {
      this.newModel = { name: '', algorithm: '' }
      this.createModelDialog = true
    },
    nextToDataIntegration() {
      if (!this.newModel.name || !this.newModel.algorithm) {
        Message.warning('请填写模型名称并选择算法类型')
        return
      }
      this.createModelDialog = false
      this.dataIntegrationDialog = true
    },
    handleFileChange(type) {
      return (file, fileList) => {
        this.dataFiles[type] = fileList
      }
    },
    nextToTrainConfig() {
      // 简单校验
      if (!this.dataFiles.fault.length || !this.dataFiles.param.length || !this.dataFiles.maintain.length) {
        Message.warning('请导入所有数据文件')
        return
      }
      this.dataIntegrationDialog = false
      this.trainConfigDialog = true
    },
    startTrain() {
      this.trainLoading = true
      setTimeout(() => {
        // 随机生成训练结果
        const accuracy = (90 + Math.random() * 10).toFixed(2)
        const mse = (Math.random() * 10).toFixed(2)
        const r2 = (0.8 + Math.random() * 0.2).toFixed(2)
        this.trainResult = { accuracy, mse, r2 }
        this.trainLoading = false
        this.trainResultDialog = true
      }, 1800)
    },
    finishTrain() {
      // 新增模型
      const id = Date.now()
      const now = new Date()
      const model = {
        id,
        name: this.newModel.name,
        algorithm: this.newModel.algorithm,
        status: 'running',
        progress: 100,
        accuracy: Number(this.trainResult.accuracy),
        created: now.toISOString().slice(0, 10),
        updated: now.toISOString().replace('T', ' ').slice(0, 16)
      }
      this.models.push(model)
      this.recentActivities.unshift({
        model: model.name,
        action: '模型训练',
        time: model.updated,
        user: '系统',
        status: '进行中'
      })
      this.trainResultDialog = false
      Message.success('模型训练完成')
    },

    // 模型管理
    viewModel(model) {
      Message.info(`查看模型：${model.name}`)
    },
    editModel(model) {
      Message.info(`编辑模型：${model.name}`)
    },
    deleteModel(model) {
      this.$confirm(`确定要删除模型【${model.name}】吗？`, '提示', {
        type: 'warning'
      }).then(() => {
        this.models = this.models.filter(m => m.id !== model.id)
        Message.success('删除成功')
      })
    },

    // 数据更新
    openDataUpdate() {
      // 新数据自动纳入训练数据，动态调整参数
      this.dataUpdateDialog = true
      // 模拟动态更新
      setTimeout(() => {
        this.models.forEach(m => {
          if (m.status === 'running') {
            m.accuracy = Number((m.accuracy + Math.random() * 2 - 1).toFixed(2))
            m.updated = new Date().toISOString().replace('T', ' ').slice(0, 16)
          }
        })
        this.recentActivities.unshift({
          model: '全部模型',
          action: '数据动态更新',
          time: new Date().toISOString().replace('T', ' ').slice(0, 16),
          user: '系统',
          status: '已完成'
        })
        this.saveData()
      }, 1200)
    },

    // 算法分布图
    drawAlgoChart() {
      if (!this.$refs.algoChart) return
      const ctx = this.$refs.algoChart.getContext('2d')
      ctx.clearRect(0, 0, 200, 200)
      // 统计算法分布
      const algoCount = {}
      this.models.forEach(m => {
        algoCount[m.algorithm] = (algoCount[m.algorithm] || 0) + 1
      })
      const algos = Object.keys(algoCount)
      const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C']
      const total = this.models.length
      let start = 0
      algos.forEach((algo, i) => {
        const angle = (algoCount[algo] / total) * Math.PI * 2
        ctx.beginPath()
        ctx.moveTo(100, 100)
        ctx.arc(100, 100, 80, start, start + angle)
        ctx.closePath()
        ctx.fillStyle = colors[i % colors.length]
        ctx.fill()
        start += angle
      })
      // 图例
      algos.forEach((algo, i) => {
        ctx.fillStyle = colors[i % colors.length]
        ctx.fillRect(10, 170 + i * 18, 14, 14)
        ctx.fillStyle = '#333'
        ctx.font = '12px Arial'
        ctx.fillText(algo, 30, 182 + i * 18)
      })
    }
  }
}
</script>

<style scoped>
.fault-prediction-modeling {
  padding: 24px;
  background: #f5f7fa;
  min-height: 100vh;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
}
.stat-title {
  font-size: 14px;
  color: #888;
}
.stat-value {
  font-size: 28px;
  font-weight: bold;
  margin-top: 8px;
}
.model-tabs {
  margin-top: 18px;
}
.model-card {
  margin-bottom: 18px;
}
.model-title {
  font-weight: bold;
  font-size: 16px;
}
.model-algo {
  color: #888;
  margin-bottom: 8px;
}
.model-actions {
  margin-top: 10px;
  display: flex;
  gap: 8px;
}
.trend-card {
  margin-top: 18px;
}
.activity-card {
  margin-top: 18px;
}
</style>
